<?php
/**
 * Aero - Xistins Technologies PHP Framework
 * 
 * LICENSE
 * This source file is subject to the New BSD license that is bundled 
 * with this package in the LICENSE.txt. It is also available through 
 * the world-wide-web at this URL: http://dev.xistins.com/license/production
 * If you did not receive a copy of this license and are unable to obtain
 * it through the world-wide-web, please send an email to 
 * license@xistins.com so we can send you a copy immediately.
 * 
 * @category   Aero
 * @package    Aero_View
 * @copyright  http://dev.xistins.com/license/production     New BSD
 * @version    $Id: View.php 4 2009-11-14 18:35:45Z csouth@xistins.com $
 */

/**
 * View Class
 * 
 * @category   Aero
 * @package    Aero_View
 * @copyright  http://dev.xistins.com/license/production     New BSD
 * @version    $Id: View.php 4 2009-11-14 18:35:45Z csouth@xistins.com $
 */
class Aero_View
{
    /**
     * View script variables
     * @var array
     */
    protected $_data = array();

    /**
     * View Helpers
     * @var array
     */
    protected $_helpers = array();

    /**
     * Default Layout
     * @var string
     */
    protected $_layout = '../application/views/layouts/layout.phtml';

    /**
     * Global Views Path
     * @var string
     */
    protected $_viewPath = '../application/views';

    /**
     * Render a view script
     * 
     * @param  string $viewScript
     * @return string
     */
    public function render($viewScript)
    {
        ob_start();
        include($viewScript);
        return ob_get_clean();
    }

    /**
     * Render layout
     * 
     * @return string
     */
    public function renderLayout()
    {
        return $this->render($this->_layout);
    }

    /**
     * Assign view script variable
     * 
     * @param  string $name
     * @param  mixed $value
     * @return void
     */
    public function __set($name, $value)
    {
        $this->_data[$name] = $value;
    }

    /**
     * Get view script variable
     * 
     * @param  string $name
     * @return void
     */
    public function __get($name)
    {
        if(isset($this->_data[$name])) {
            return $this->_data[$name];
        }

        return NULL;
    }

    /**
     * Check if script variable isset
     * 
     * @param  string $name
     * @return void
     */
    public function __isset($name)
    {
        return isset($this->_data[$name]);
    }

    /**
     * Unset a script variable
     * 
     * @param  string $name
     * @return void
     */
    public function __unset($name)
    {
        if(isset($this->_data[$name])) {
            unset($this->_data[$name]);
        }
    }

    /**
     * Set Layout
     * 
     * @param  string $layout
     * @return void
     */
    public function setLayout($layout)
    {
        $this->_layout = $layout;
    }

    /**
     * Call magic method for view helpers
     * 
     * @param  string $name
     * @param  array $args
     * @return string 
     */
    public function __call($name, $args)
    {
        $helper = $this->_getHelper($name);

        if(!$helper) {
            Aero_Loader::loadClass('Aero_View_Exception');
            throw new Aero_View_Exception("Requested method $name was not 
                                           found in Aero_View and wasn't caught 
                                           by __call()");
        }

        return call_user_func_array(
            array($helper, $name),
            $args
        );
    }

    /**
     * Get loader.
     * Pulls from an internal array. If the helper isn't available create it.
     * 
     * @param  string $name
     * @throws Aero_View_Exception non-existant helper.
     * @return Aero_View_Helper
     */
    protected function _getHelper($name)
    {
        if(!isset($this->_helpers[$name])) {
            $class = 'Aero_View_Helper_'.ucfirst($name);

            if(!Aero_Loader::loadClass($class)) {
                require_once 'Aero/View/Exception.php';
                throw new Aero_View_Exception("Unable to find requested view: $name");
            }

            $reflection = new ReflectionClass($class);
            $this->_helpers[$name] = $reflection->newInstance();
            return $this->_helpers[$name];
        } else {
            return $this->_helpers[$name];
        }

        return false;
    }
}